package com.aquarium.bt;

import com.aquarium.config.BTCommand;

import android.os.PowerManager;
import android.util.Log;

public class DataInterpreter {

	private final static String TAG = "DataInterpreter";

	/**
	 * parse and unpack a original data received from remote BT device
	 * 
	 * @param data
	 *            The data send by remote BT device
	 * @return Local {@link DataStruct}
	 */
	public static DataStruct unpack(byte[] data) {
		if (data.length < 4) {
			Log.e(TAG, "data unpack error, length = " + data.length);
			return null;
		}
		DataStruct struct = new DataStruct();
		struct.prefix = data[0];
		struct.id = data[1];
		struct.code = data[2];
		struct.length = data[3];
		if (struct.length < 0) {
			return null;
		}
		struct.data = new byte[struct.length];
		for (int i = 0; i < struct.length; i++) {
			struct.data[i] = data[i + 4];
		}
		return struct;
	}

	/**
	 * pack a {@link DataStruct} to String
	 * 
	 * @param cmd
	 *            The cmd to pack
	 * @return The package
	 */
	public static byte[] pack(DataStruct cmd) {
		if (cmd.length < 0) {
			return null;
		}
		byte[] data = new byte[cmd.length + 4];
		data[0] = cmd.prefix;
		data[1] = cmd.id;
		data[2] = cmd.code;
		data[3] = cmd.length;
		for (int i = 0; i < cmd.length; i++) {
			data[i + 4] = cmd.data[i];
		}
		return data;
	}

	/**
	 * Update the data part in {@link DataStruct} to PH min and max value
	 * 
	 * @param data
	 *            The data to unpack
	 * @return Index 0 is min PH value and index 1 is max PH value
	 */
	public static float[] unpackPhAlarmData(byte[] data) {
		float[] value = new float[2];
		if (data.length != BTCommand.PH_ALARM_DATA_LENGTH) {
			Log.e(TAG, "data length error = " + data.length);
			return null;
		}
		value[0] = ((float) (data[0] * 10 + data[1])) / 10;
		value[1] = ((float) (data[2] * 10 + data[3])) / 10;
		return value;
	}

	/**
	 * Update the data part in {@link DataStruct} to Temperature min and max
	 * value
	 * 
	 * @param data
	 *            The data to unpack
	 * @return Index 0 is min Temperature value and index 1 is max Temperature
	 *         value
	 */
	public static float[] unpackTemperatureAlarmData(byte[] data) {
		float[] value = new float[2];
		if (data.length != BTCommand.TEMPRATURE_ALARM_DATA_LENGTH) {
			Log.e(TAG, "data length error = " + data.length);
			return null;
		}
		value[0] = data[0];
		value[1] = data[1];
		return value;
	}

	/**
	 * Update the data part in {@link DataStruct} to Oxygen min and max value
	 * 
	 * @param data
	 *            The data to unpack
	 * @return Index 0 is min Oxygen value and index 1 is max Oxygen value
	 */
	public static float[] unpackOxygenAlarmData(byte[] data) {
		float[] value = new float[2];
		if (data.length != BTCommand.OXYGEN_ALARM_DATA_LENGTH) {
			Log.e(TAG, "data length error = " + data.length);
			return null;
		}
		value[0] = (float) (data[0] * Math.pow(16, 2) + data[1]);
		value[1] = (float) (data[2] * Math.pow(16, 2) + data[3]);
		return value;
	}

	/**
	 * Update the data part in {@link DataStruct} to Conductivity min and max
	 * value
	 * 
	 * @param data
	 *            The data to unpack
	 * @return Index 0 is min Conductivity value and index 1 is max Conductivity
	 *         value
	 */
	public static float[] unpackConductivityAlarmData(byte[] data) {
		float[] value = new float[2];
		if (data.length != BTCommand.CONDUCTIVITY_ALARM_DATA_LENGTH) {
			Log.e(TAG, "data length error = " + data.length);
			return null;
		}
		value[0] = (float) ((data[0] * 1000 + data[1] * Math.pow(16, 2) + data[2]) / 1000);
		value[1] = (float) ((data[3] * 1000 + data[4] * Math.pow(16, 2) + data[5]) / 1000);
		return value;
	}

	/**
	 * Update the data part in {@link DataStruct} to Water Level min and max
	 * value
	 * 
	 * @param data
	 *            The data to unpack
	 * @return Index 0 is min Water Level value and index 1 is max Water Level
	 *         value
	 */
	public static float[] unpackWaterLevelAlarmData(byte[] data) {
		float[] value = new float[2];
		if (data.length != BTCommand.WATER_LEVEL_ALARM_DATA_LENGTH) {
			Log.e(TAG, "data length error = " + data.length);
			return null;
		}
		value[0] = (float) (data[0] * Math.pow(16, 2) + data[1]);
		value[1] = (float) (data[2] * Math.pow(16, 2) + data[3]);
		return value;
	}

	public static float unpackPhData(byte[] data) {
		float value = 0;
		if (data.length != BTCommand.PH_DATA_LENGTH) {
			Log.e(TAG, "data length error = " + data.length);
			return value;
		}
		value = ((int) (data[0] & 0xff) * 10 + (int) (data[1] & 0xff)) / 10;
		return value;
	}

	public static float unpackTemperatureData(byte[] data) {
		float value = 0;
		if (data.length != BTCommand.TEMPRATURE_DATA_LENGTH) {
			Log.e(TAG, "data length error = " + data.length);
			return value;
		}
		value = (int)(data[0] & 0xff);
		return value;
	}

	public static float unpackOxygenData(byte[] data) {
		float value = 0;
		if (data.length != BTCommand.OXYGEN_DATA_LENGTH) {
			Log.e(TAG, "data length error = " + data.length);
			return value;
		}
		value = (float) ((int) (data[0] & 0xff) * (int) Math.pow(16, 2) + (int) (data[1] & 0xff));
		return value;
	}

	public static float unpackConductivityData(byte[] data) {
		float value = 0;
		if (data.length != BTCommand.CONDUCTIVITY_DATA_LENGTH) {
			Log.e(TAG, "data length error = " + data.length);
			return value;
		}
		value = (float) ((int) (data[0] & 0xff) * 1000 + (int) (data[1] & 0xff)
				* (int) Math.pow(16, 2) + (int) (data[2] & 0xff)) / 1000;
		return value;
	}

	public static float unpackWaterLevelData(byte[] data) {
		float value = 0;
		if (data.length != BTCommand.WATER_LEVEL_DATA_LENGTH) {
			Log.e(TAG, "data length error = " + data.length);
			return value;
		}
		value = (float) ((int) (data[0] & 0xff) * (int) Math.pow(16, 2) + (int) (data[1] & 0xff));
		return value;
	}
}
